package com.jiuyin.dianjing.api.Observer;

import android.content.Context;
import android.content.Intent;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.jiuyin.dianjing.api.data.BasicResponse;
import com.jiuyin.dianjing.app.HelperApplication;
import com.jiuyin.dianjing.util.ProgressDialogUtil;
import com.jiuyin.dianjing.util.ToastUtil;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

import static com.jiuyin.dianjing.api.constant.ApiConstant.RESULT_OK;
import static com.jiuyin.dianjing.api.constant.ApiConstant.RESULT_RE_LOGIN;
import static com.jiuyin.dianjing.api.enums.ExceptionReason.CANCEL_BY_USER;
import static com.jiuyin.dianjing.api.enums.ExceptionReason.onDealError;
import static com.jiuyin.dianjing.constant.AppConstant.ACTION_NEED_LOGIN;

/**
 * 网络请求
 */
public abstract class BasicResponseObserver<N extends BasicResponse> implements Observer<N> {
    private Disposable disposable;
    private ProgressDialogUtil psd;
    /**
     * mShowToast为true显示网络返回非成功提示
     */
    private boolean mShowToast = false;

    private boolean mShowProgress = false;

    /**
     * 不可取消，不能取消请求的默认
     *
     * @param context
     */
    public BasicResponseObserver(Context context) {
        this(context, false, false);
    }

    /**
     * 进度条可以消失，是否取消请求
     *
     * @param context
     * @param cancelRequest
     */
    public BasicResponseObserver(Context context, boolean cancelRequest) {
        this(context, true, cancelRequest);
    }

    public BasicResponseObserver(Context context, boolean cancelable, boolean cancelRequest) {
        this(context, cancelable, cancelRequest, true);
    }

    /**
     * 默认显示进度条
     *
     * @param context
     * @param cancelable    是否显示进度条 true(显示）
     * @param cancelRequest 请求是否可以取消 true(可以取消)
     * @param showToast     是否显示Toast true(显示)
     */
    public BasicResponseObserver(Context context, boolean cancelable, boolean cancelRequest, boolean showToast) {
        this(context, cancelable, cancelRequest, showToast, true);
    }


    public BasicResponseObserver(Context context, boolean cancelable, boolean cancelRequest, boolean showToast, boolean showProgress) {
        mShowToast = showToast;
        mShowProgress = showProgress;
        if (showProgress) {
            psd = new ProgressDialogUtil();
            if (cancelRequest) {
                psd.showProgress(context, cancelable, dialog -> this.cancel());
            } else {
                psd.showProgress(context, cancelable, null);
            }
        }
    }

    @Override
    public void onSubscribe(Disposable d) {
        disposable = d;
    }

    @Override
    public void onNext(N n) {
        if (RESULT_OK == n.getCode()) {
            onSuccess(n);
        } else {
            String msg = n.getMsg();
            if (mShowToast) {
                ToastUtil.showLong(msg);
            }
            onFail(msg);
        }
        if (RESULT_RE_LOGIN == n.getCode()) {
            Context context = HelperApplication.getContext();
            LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ACTION_NEED_LOGIN));
        }
    }

    @Override
    public void onError(Throwable e) {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
        onDealError(e);
    }

    @Override
    public void onComplete() {
        if (mShowProgress) {
            if (null != psd) {
                psd.dismissProgress();
            }
        }
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }

    protected abstract void onSuccess(N t);

    protected abstract void onFail(String msg);

    private void cancel() {
        onError(new Throwable(CANCEL_BY_USER.name()));
    }
}
